package de.tsystems.dict.api.impl;

import com.google.common.base.Preconditions;
import de.tsystems.dict.api.TranslationService;
import de.tsystems.dict.api.WordService;
import de.tsystems.dict.model.Language;
import de.tsystems.dict.model.Translation;
import de.tsystems.dict.model.Word;
import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;
import javax.inject.Named;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;

@Named("wordService")
class WordServiceImpl implements WordService {

    @Inject
    @Named("wordDao")
    private WordDao wordDao;

    @Inject
    @Named("translationService")
    private TranslationService translationService;

    public void setWordDao(WordDao wordDao) {
        this.wordDao = wordDao;
    }

    @Override
    public WordDao getWordDao() {
        return wordDao;
    }

    public TranslationService getTranslationService() {
        return translationService;
    }

    @Override
    @Transactional
    public Word save(Word word) {
        Preconditions.checkNotNull(word);
        Preconditions.checkArgument(StringUtils.isNotBlank(word.getText()), "Text cannot be empty");
        Preconditions.checkArgument(word.getLanguage() != null, "Language cannot be null");
        return wordDao.save(word);
    }

    @Override
    @Transactional(readOnly = true)
    public Word getById(Serializable id) {
        Preconditions.checkNotNull(id);
        return wordDao.getById(id);
    }

    @Override
    @Transactional(readOnly = true)
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public List<Word> listAll() {
        return wordDao.listAll();
    }

    @Override
    @Transactional(readOnly = true)
    public Word findByTextAndLanguage(String text, Language language) {
        Preconditions.checkArgument(StringUtils.isNotBlank(text));
        Preconditions.checkNotNull(language);
        Preconditions.checkNotNull(language.getId());
        return wordDao.findByTextAndLanguage(
                StringUtils.trimToEmpty(StringUtils.lowerCase(text)),
                language
        );
    }

    @Override
    @Transactional
    public Word create(String text, Language language) {
        Preconditions.checkArgument(StringUtils.isNotBlank(text));
        Preconditions.checkNotNull(language);
        Preconditions.checkNotNull(language.getId());
        return wordDao.create(text, language);
    }


    @Override
    @Transactional
    public void remove(@NotNull Word word) {
        for (Translation translation : wordDao.getTranslations(word)) {
            translationService.remove(translation);
        }
        wordDao.remove(word);
    }



}